<script setup>
import { ref, markRaw } from "vue";

import DiyHeader from "./components/diyHeader.vue";

import { componentList } from "@/components/mobilePage/index";
import * as _ from "lodash-es";
import { nanoid } from "nanoid";
import draggable from "vuedraggable";
import { moveUp, moveDown, removeComponent } from "@/utils/move";
import ImageUploader from "@/components/Upload.vue";

defineOptions({
  name: "diy",
});

// 标记原始组件列表中的组件对象
const rawComponentList = componentList.map((comp) => ({
  ...comp,
  component: markRaw(comp.component), // 关键修复：标记组件对象
}));

const leftMenu = ref([]);
const centerList = ref([]);
const selectedComponent = ref(null); // 修复：添加缺失的selectedComponent声明

const categorizeComponents = () => {
  const categories = [
    {
      title: "基础组件",
      list: [],
      isOpen: true,
      type: 0,
    },
    {
      title: "营销组件",
      list: [],
      isOpen: true,
      type: 1,
    },
    {
      title: "工具组件",
      list: [],
      isOpen: true,
      type: 2,
    },
  ];
  // 使用处理后的原始组件列表
  rawComponentList.forEach((component) => {
    const category = categories.find((cat) => cat.type === component.type);
    category?.list.push(component);
  });
  leftMenu.value = categories;
};

categorizeComponents();

const cloneDog = (item) => {
  return {
    ...item,
    id: nanoid(),
    component: markRaw(item.component),
    props: { ...item.props },
  };
};

const selectComponent = (element) => {
  selectedComponent.value = element;
  console.log(element);
};

// 新增图片管理方法
const handleFileUpload = async (event, propName) => {
  const files = event.target.files;
  if (!files.length) return;

  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    const imageUrl = await convertToBase64(file);

    // 添加到当前组件的imageList
    selectedComponent.value.props[propName].push({
      url: imageUrl,
      name: file.name,
      id: nanoid(),
    });
  }

  // 重置input以允许再次选择相同文件
  event.target.value = "";
};

const convertToBase64 = (file) => {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
  });
};

const removeImage = (propName, index) => {
  selectedComponent.value.props[propName].splice(index, 1);
};

const moveImage = (propName, fromIndex, direction) => {
  const newIndex = fromIndex + direction;
  const arr = selectedComponent.value.props[propName];

  if (newIndex >= 0 && newIndex < arr.length) {
    const temp = arr[fromIndex];
    arr[fromIndex] = arr[newIndex];
    arr[newIndex] = temp;
  }
};

const addGridItem = (gridList) => {
  gridList.push({
    id: nanoid(),
    text: "新项目",
    url: [],
  });
};
</script>

<template>
  <div class="wrapper">
    <div class="header">
      <DiyHeader />
    </div>
    <div class="content-grid">
      <div class="left-panel">
        <div class="p-2">
          <div
            class="cursor-pointer rounded border p-3 mb-2 hover:shadow-md"
            v-for="(item, index) in leftMenu"
            :key="index"
          >
            <div
              class="flex items-center justify-center"
              @click="item.isOpen = !item.isOpen"
            >
              <div class="mr-1">{{ item.title }}</div>
              <div class="iconfont icon-right" v-if="!item.isOpen"></div>
              <div class="iconfont icon-down" v-else></div>
            </div>

            <draggable
              class="dragArea list-group mt-2"
              v-model="item.list"
              :group="{ name: 'people', pull: 'clone', put: false }"
              :clone="cloneDog"
              item-key="id"
              :dragClass="'dragClass'"
            >
              <template #item="{ element, index }">
                <div class="list-group-item" v-show="item.isOpen">
                  <div>
                    <div class="position" style="display: none">
                      释放鼠标将组件添加到此处
                    </div>
                    <div class="iconfont text-2xl" :class="element.icon"></div>
                    <p>{{ element.cname }}</p>
                  </div>
                </div>
              </template>
            </draggable>
          </div>
        </div>
      </div>

      <div class="center-panel py-5">
        <div
          class="flex flex-col relative min-h-full w-[379px] mx-auto bg-gray-50"
        >
          <!-- 顶部 -->
          <div>
            <div class="h-[20px] bg-white">
              <img
                src="@/assets/images/electric.png"
                class="block min-w-full"
              />
            </div>
            <div class="h-[35px] flex items-center justify-center bg-white">
              首页
            </div>
          </div>

          <draggable
            v-model="centerList"
            :group="{ name: 'people' }"
            item-key="id"
            class="flex-1"
          >
            <template #item="{ element, index }">
              <div
                class="relative cursor-pointer"
                :class="{
                  'selected-c':
                    selectedComponent && selectedComponent.id === element.id,
                }"
                @click="selectComponent(element)"
              >
                <div
                  class="c-name"
                  :class="{
                    selected:
                      selectedComponent && selectedComponent.id === element.id,
                  }"
                >
                  {{ element.cname }}
                </div>

                <div
                  class="c-oper"
                  v-if="
                    selectedComponent && selectedComponent.id === element.id
                  "
                >
                  <button
                    @click.stop="moveUp(centerList, index)"
                    title="上移"
                    :disabled="index === 0"
                  >
                    <div class="iconfont icon-arrowup"></div>
                  </button>
                  <button
                    @click.stop="moveDown(centerList, index)"
                    :disabled="index === centerList.length - 1"
                    title="下移"
                  >
                    <div class="iconfont icon-arrowdown"></div>
                  </button>
                  <button
                    @click.stop="removeComponent(centerList, index)"
                    title="删除"
                  >
                    <div class="iconfont icon-delete"></div>
                  </button>
                </div>

                <component
                  :is="element.component"
                  :key="element.id"
                  v-bind="element.props"
                />
              </div>
            </template>
          </draggable>
        </div>
      </div>

      <div class="right-panel">
        <template v-if="selectedComponent">
          <div
            v-for="(propConfig, propName) in selectedComponent.component.props"
            :key="propName"
            class="p-4"
          >
            <label class="property-label">
              {{ propConfig.title }}
            </label>

            <div class="mt-1">
              <template v-if="propConfig.ctype === 'number'">
                <el-input-number
                  v-model="selectedComponent.props[propName]"
                  :min="1"
                />
              </template>

              <template v-else-if="propConfig.ctype === 'text'">
                <el-input v-model="selectedComponent.props[propName]" />
              </template>

              <template v-else-if="propConfig.ctype === 'imageList'">
                <div class="image-list-editor">
                  <div
                    v-for="(image, index) in selectedComponent.props[propName]"
                    :key="image.id"
                    class="image-item"
                  >
                    <img :src="image.url" class="thumbnail" />
                    <div class="image-actions">
                      <button
                        @click.stop="moveImage(propName, index, -1)"
                        title="上移"
                        :disabled="index === 0"
                      >
                        <div class="iconfont icon-arrowup"></div>
                      </button>
                      <button
                        @click.stop="moveImage(propName, index, 1)"
                        :disabled="index === centerList.length - 1"
                        title="下移"
                      >
                        <div class="iconfont icon-arrowdown"></div>
                      </button>
                      <button
                        @click.stop="removeImage(propName, index)"
                        title="删除"
                        class="text-red-500"
                      >
                        <div class="iconfont icon-delete"></div>
                      </button>
                    </div>
                  </div>

                  <label class="upload-btn">
                    + 添加图片
                    <input
                      type="file"
                      accept="image/*"
                      multiple
                      @change="(e) => handleFileUpload(e, propName)"
                      class="hidden"
                    />
                  </label>
                </div>
              </template>

              <template v-else-if="propConfig.ctype === 'gridList'">
                <div class="flex flex-col gap-2">
                  <div
                    v-for="(item, index) in selectedComponent.props[propName]"
                    :key="item.id"
                    class="border rounded p-2 flex items-center"
                  >
                    <div class="flex-shrink-0">
                      <ImageUploader v-model="item.url" />
                    </div>

                    <el-input
                      v-model="item.text"
                      placeholder="请输入文字"
                      class="mx-4"
                    />

                    <div class="flex items-center">
                      <el-button
                        circle
                        @click.stop="moveImage(propName, index, -1)"
                        title="上移"
                        :disabled="index === 0"
                      >
                        <div class="iconfont icon-arrowup"></div>
                      </el-button>

                      <el-button
                        circle
                        @click.stop="moveImage(propName, index, 1)"
                        :disabled="
                          index === selectedComponent.props[propName].length - 1
                        "
                        title="下移"
                      >
                        <div class="iconfont icon-arrowdown"></div>
                      </el-button>

                      <el-button
                        circle
                        @click.stop="removeImage(propName, index)"
                        title="删除"
                        class="text-red-500"
                      >
                        <div class="iconfont icon-delete"></div>
                      </el-button>
                    </div>
                  </div>

                  <label
                    class="upload-btn"
                    @click="addGridItem(selectedComponent.props[propName])"
                  >
                    + 添加选项
                  </label>
                </div>
              </template>
            </div>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
/* 新增图片编辑器样式 */
.image-list-editor {
  @apply flex flex-col gap-2;
}

.image-item {
  @apply border rounded p-2 flex items-center;
}

.thumbnail {
  @apply w-16 h-16 object-cover rounded mr-2;
}

.image-actions {
  @apply flex gap-1 ml-auto;
}

.upload-btn {
  @apply mt-2 p-2 border border-dashed rounded 
         text-center cursor-pointer hover:bg-gray-100;
}

.property-control {
  @apply w-full p-1 border rounded;
}

.selected-c {
  @apply ring-2 ring-blue-500;
}

.c-name {
  @apply absolute top-0 left-[-100px] bg-white w-[86px] text-center py-2 rounded-sm text-sm;

  &::before {
    content: "";
    position: absolute;
    width: 10px;
    height: 10px;
    background: #fff;
    transform: rotate(45deg);
    top: 50%;
    right: -5px;
    margin-top: -5px;
  }

  &.selected {
    @apply bg-blue-600 text-white;
  }

  &.selected::before {
    @apply bg-blue-600;
  }
}

.c-oper {
  @apply absolute top-0 right-[-50px] bg-white w-[40px] text-center py-2 rounded-sm flex flex-col;
}

.wrapper {
  @apply h-screen w-screen grid grid-rows-[auto_1fr] overflow-hidden;

  .header {
    @apply flex h-[50px] items-center border-b p-3 bg-blue-600 text-white text-sm;
  }

  .content-grid {
    @apply grid h-full w-full grid-cols-[auto_1fr_auto] min-h-0;

    .left-panel {
      @apply w-[400px] border-r h-full overflow-y-auto;
    }

    .center-panel {
      @apply bg-gray-100 h-full overflow-y-auto;
    }

    .right-panel {
      @apply w-[400px] border-l h-full overflow-y-auto;
    }
  }
}

.dragArea.list-group {
  display: flex;
  flex-wrap: wrap;

  .list-group-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 74px;
    height: 66px;
    margin-right: 17px;
    margin-bottom: 10px;
    font-size: 12px;
    color: #666;
    cursor: pointer;
    border-radius: 5px;
    text-align: center;

    &:hover {
      box-shadow: 0 0 5px 0 rgba(24, 144, 255, 0.3);
      border-right: 5px;
      transform: scale(1.1);
      transition: all 0.2s;
    }

    &:nth-child(3n) {
      margin-right: 0;
    }
  }
}
</style>
